<script lang="ts">
import { defineComponent, shallowReactive, inject, onMounted, onBeforeUnmount, ref, h, nextTick, shallowRef, getCurrentInstance } from 'vue'
import { ElTableColumn } from 'element-plus'
import { uuid } from '/@/utils/random'
import baTableClass from '/@/utils/baTable'

export default defineComponent({
    name: 'Column',
    props: {
        attr: {
            type: Object,
            required: true,
        },
    },
    setup(props, { slots }) {
        // 使用shallowReactive而非reactive来避免深度响应性引起的不必要渲染
        const attr = shallowReactive({...props.attr}) 
        attr['column-key'] = attr['column-key'] ? attr['column-key'] : attr.prop || uuid()
        
        // 组件挂载状态标志
        const isMounted = ref(false)
        const isDestroyed = ref(false)
        
        // 获取组件实例，用于检查组件是否已经卸载
        const instance = getCurrentInstance()
        
        // 从父组件获取表格实例
        const baTable = inject<baTableClass>('tableData')
        
        // 列宽记忆相关
        const savedWidth = shallowRef<number | undefined>(undefined)
        
        // 清理资源的回调函数
        let cleanup: (() => void) | null = null
        
        onMounted(() => {
            // 确保在mounted后再设置状态
            nextTick(() => {
                if (isDestroyed.value) return
                isMounted.value = true
            })
            
            // 挂载后加载列宽设置
            if (baTable && attr.prop && baTable.rememberColumnWidth) {
                try {
                    // 加载保存的列宽
                    const width = baTable.getColumnWidth(attr.prop as string)
                    if (width && !isDestroyed.value) {
                        savedWidth.value = width
                    }
                } catch (err) {
                    console.error('加载列宽设置失败:', err)
                }
            }
        })
        
        // 在组件卸载前清理资源
        onBeforeUnmount(() => {
            isDestroyed.value = true
            isMounted.value = false
            if (cleanup) {
                cleanup()
                cleanup = null
            }
        })
        
        // 处理列宽变化事件
        const handleColumnWidthChange = (newWidth: number) => {
            if (isDestroyed.value || !isMounted.value || !baTable || !attr.prop) return
            
            try {
                // 检查组件是否已经卸载
                if (instance && instance.isUnmounted) return
                
                // 保存新的列宽
                if (baTable.rememberColumnWidth) {
                    baTable.updateColumnWidth(attr.prop as string, newWidth)
                    if (!isDestroyed.value) {
                        savedWidth.value = newWidth
                    }
                }
            } catch (err) {
                console.error('保存列宽失败:', err)
            }
        }
        
        // 准备列属性
        if (baTable && attr.prop && baTable.rememberColumnWidth) {
            // 保存原始事件处理函数
            const originalHeaderDragend = attr.onHeaderDragend
            
            // 替换为安全的事件处理函数
            attr.onHeaderDragend = (newWidth: number, ...args: any[]) => {
                if (isDestroyed.value) return
                
                handleColumnWidthChange(newWidth)
                
                // 调用原始处理函数
                if (typeof originalHeaderDragend === 'function' && !isDestroyed.value) {
                    try {
                        originalHeaderDragend(newWidth, ...args)
                    } catch (e) {
                        console.error('调用原始列宽变化处理函数失败:', e)
                    }
                }
            }
        }

        // 应用保存的列宽
        if (savedWidth.value && !attr.width) {
            attr.width = savedWidth.value
        }
        
        // 使用函数式组件渲染，避免不必要的更新
        return () => {
            // 如果组件已销毁，返回null
            if (isDestroyed.value || !isMounted.value) return null
            
            try {
                // 应用最新的列宽
                if (savedWidth.value && !attr.width) {
                    attr.width = savedWidth.value
                }
                
                // 返回渲染的表格列
                return h(ElTableColumn, attr, slots)
            } catch (error) {
                console.error('渲染表格列时出错:', error)
                // 出错时返回null，避免应用崩溃
                return null
            }
        }
    },
})
</script>
